const jwt = require('jsonwebtoken');
const config = require('../../config');
const APIError = require('../../rest_api').APIError;
const { UserModel, RoleModel } = require('../../db/index');
const { isLogin } = require('../lib'); // 验证登录与角色
const bcrypt = require('bcrypt');

function userYanZheng(username, password) {
    const passRep = /^[A-Za-z0-9]$/;
    if (username.length === 0) {
        throw new APIError('internal:user_regist_username_error', '请填写注册名称');
    }
    if (passRep.test(password)) {
        console.log(password);
        throw new APIError('internal:user_regist_password_error', '密码不符合规则(6-20位字母数字组合)');
    }
}

module.exports = {
    // 注册
    'POST /api/v1/register': async (ctx, next) => {
        const body = ctx.request.body;
        const username = body.username.trimAll();
        const cname = body.cname || '论坛用户' + new Date().valueOf();
        let password = body.password;

        // 用户名密码验证
        userYanZheng(username, password);

        const usernameRepeat = await UserModel.find({
            username
        });

        const user = new UserModel({
            username,
            password,
            cname
        });

        try {
            const data = await user.save();
            // 返回数据
            ctx.rest({
                message: '注册成功',
                data
            });
        } catch (error) {
            if (error.code === 11000) {
                throw new APIError('internal:user_regist_username_error', '此用户名已存在');
            } else {
                throw new APIError('internal:user_regist_error', '注册失败');
            }
        }
        await next();
    },
    // 登录
    'POST /api/v1/login': async (ctx, next) => {
        const body = ctx.request.body;
        const username = body.username;
        const password = body.password;

        // 用户名密码验证
        userYanZheng(username, password);

        const getUser = await UserModel.findOne({ username });
        if (getUser === null) {
            throw new APIError('internal:user_login_username_error', '用户不存在');
        }
        // 效验密码
        let isMatch;
        try {
            isMatch = await bcrypt.compare(password, getUser.password);
        } catch (error) {
            throw new APIError('internal:user_login_username_error', '登录失败，密码校验失败');
        }

        if (isMatch) {
            // 生成token
            const token = jwt.sign({ id: getUser.id }, config.secret, {
                expiresIn: '12h'
            });
            const userUp = await UserModel.findByIdAndUpdate(getUser.id, { token });
            ctx.rest({
                message: '登录成功',
                createDate: userUp.createDate,
                headImg: userUp.headImg,
                username: userUp.username,
                token
            });
        } else {
            throw new APIError('internal:user_login_username_error', '登录失败，密码错误');
        }
    },
    // 修改密码
    'PUT /api/v1/password': async (ctx, next) => {
        const body = ctx.request.body;
        const token = ctx.headers.token;
        const userId = body.userid;
        const password = body.password;
        let jmpassword;
        let userid;
        console.log(body);
        const userInfo = await UserModel.findById(userId);
        try {
            const salt = await bcrypt.genSalt(10);
            jmpassword = await bcrypt.hash(password, salt);
        } catch (error) {
            throw new APIError('internal:password_error', '密码加密失败');
        }
        // 修改别人密码时
        if (userId) {
            let userInfo;
            const user = await UserModel.findById(userId);
            if (user === null) {
                throw new APIError('user_error', '用户不存在');
            }
            // 验证登录与角色权限
            try {
                await isLogin(token, true, ['超级管理员', '管理员']);
                userid = userId;
            } catch (error) {
                throw new APIError(error.code, error.message);
            }
        } else {
            // 修改自己的密码
            // 验证登录
            try {
                const userinfo = await isLogin(token, true);
                userid = userinfo.id;
            } catch (error) {
                throw new APIError(error.code, error.message);
            }
        }
        // 通过验证开始修改
        try {
            await UserModel.findByIdAndUpdate(userid, {
                password: jmpassword,
                upDate: new Date()
            });
            ctx.rest({
                message: '密码修改成功'
            })
        } catch (error) {
            throw new APIError('internal:role_error', '密码修改失败');
        }
    },
    // 获取用户信息
    'GET /api/v1/userInfo': async (ctx, next) => {
        const body = ctx.query;
        const token = ctx.headers.token;
        const needKey = {
            username: 1,
            cname: 1,
            createDate: 1,
            headImg: 1
        };
        let info;
        // 获取用户信息
        try {
            if (!body.userid || body.userid.length === 0) {
                info = await UserModel.findOne({ token }, needKey);
            } else {
                info = await UserModel.findById(body.userid, needKey);
            }
        } catch (error) {
            console.log(error);
            throw new APIError('internal:user_info_error', '获取用户信息失败');
        }

        if (info) {
            // 返回信息
            ctx.rest(info);
        } else {
            throw new APIError('internal:user_info_undefined', '用户不存在');
        }
    }
};
